package org.lee.util;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author jackielee
 * @version 1.0
 * @description FileUtils
 * @date 2021/5/6
 */
public class FileUtils {
  private static final String[] PPTEXTS = {"ppt", "pptx", "pptm"};
  private static final String[] IMGEXTS = {"jpg", "jpeg", "png", "bmp"};

  public static String getExt(File file) {
    String fileName = file.getName();
    int index = fileName.lastIndexOf(".");
    return index == -1 ? "" : fileName.substring(index + 1);
  }

  public static String getFileName(File file) {
    String fileName = file.getName();
    int index = fileName.lastIndexOf(".");
    return index == -1 ? fileName : fileName.substring(0, index);
  }

  public static boolean checkPpt(File file) {
    String ext = getExt(file);
    return Arrays.stream(PPTEXTS).anyMatch(x -> x.equalsIgnoreCase(ext));
  }

  public static List<File> getFiles(String path) {
    File file = new File(path);
    List<File> files = new ArrayList<>();
    if (!file.exists()) {
      return files;
    }
    if (file.isDirectory()) {
      List<File> list = Arrays.asList(file.listFiles());
      files.addAll(list);
    } else {
      files.add(file);
    }
    return files;
  }

  public static boolean checkImage(File file) {
    String ext = getExt(file);
    return Arrays.stream(IMGEXTS).anyMatch(x -> x.equalsIgnoreCase(ext));
  }

  public static boolean DirExists(String path) {
    File file = new File(path);
    return file.exists() && file.isDirectory();
  }

  public static boolean checkDir(String path) {
    File file = new File(path);
    if (file.exists()) {
      return true;
    }
    return file.mkdirs();
  }

  public static void clearDir(String path) {
    File root = new File(path);
    for (File file : root.listFiles()) {
      if (file.isFile()) {
        file.delete();
        continue;
      }
      clearDir(file.getPath());
    }
    root.delete();
  }

  public static boolean fileExists(String path) {
    File file = new File(path);
    return file.exists() && file.isFile();
  }

  public static String formatPath(String path) {
    return path.toLowerCase().replace("\\", "/");
  }

  public static String getSubPath(String path, String rootPath) {
    return formatPath(path).replace(formatPath(rootPath), "");
  }

  /**
   * byte转字符串
   *
   * @param fileSize
   * @return
   */
  public static String fileSizeString(long fileSize) {
    double gb = 1024.0 * 1024 * 1024;
    double mb = 1024.0 * 1024;
    double kb = 1024.0;
    if (fileSize > gb) {
      double size = fileSize / gb;
      return String.format("%.2fGB", size);
    }
    if (fileSize > mb) {
      double size = fileSize / mb;
      return String.format("%.2fMB", size);
    }
    if (fileSize > kb) {
      double size = fileSize / kb;
      return String.format("%.2fKB", size);
    }
    return String.format("%dB", fileSize);
  }

  public static void copy(String path, String savePath, ICopying copying, ICopyLog copyLog)
      throws IOException {
    List<File> files = getFiles(path);
    checkDir(savePath);
    if (copying != null && copying.ignore(new File(path))) {
      return;
    }
    for (File file : files) {
      if (copying != null && copying.ignore(file)) {
        continue;
      }
      if (file.isFile()) {
        String target = savePath + File.separator + file.getName();
        file.setReadable(true);
        Files.copy(file.toPath(), Paths.get(target), StandardCopyOption.REPLACE_EXISTING);
        if (copyLog != null) {
          copyLog.log(String.format("copy the %s to %s", file.getPath(), target));
        }
        continue;
      }
      copy(file.getPath(), savePath + File.separator + file.getName(), copying, copyLog);
    }
  }

  public static void copy(String path, String savePath) throws IOException {
    copy(path, savePath, null, null);
  }

  public interface ICopying {
    boolean ignore(File file);
  }

  public interface ICopyLog {
    void log(String message);
  }
}
